home *** CD-ROM | disk | FTP | other *** search
/ Usenet 1993 July / InfoMagic USENET CD-ROM July 1993.ISO / sources / misc / volume6 / yahp2ps / part04 < prev    next >
Encoding:
Internet Message Format  |  1989-02-03  |  26.5 KB

  1. Path: xanth!nic.MR.NET!csd4.milw.wisc.edu!leah!itsgw!steinmetz!uunet!allbery
  2. From: allbery@uunet.UU.NET (Brandon S. Allbery - comp.sources.misc)
  3. Newsgroups: comp.sources.misc
  4. Subject: v06i006: HPGL to PostScript converter (Part 4 of 6)
  5. Message-ID: <46902@uunet.UU.NET>
  6. Date: 21 Jan 89 20:31:03 GMT
  7. Sender: allbery@uunet.UU.NET
  8. Reply-To: federico@actisb.UUCP (Federico Heinz)
  9. Organization: ACTIS in Berlin GmbH, W. Germany
  10. Lines: 925
  11. Approved: allbery@uunet.UU.NET (Brandon S. Allbery - comp.sources.misc)
  12.  
  13. Posting-number: Volume 6, Issue 6
  14. Submitted-by: federico@actisb.UUCP (Federico Heinz)
  15. Archive-name: yahp2ps/part04
  16.  
  17. #! /bin/sh
  18. # This is a shell archive.  Remove anything before this line, then unpack
  19. # it by saving it into a file and typing "sh file".  To overwrite existing
  20. # files, type "sh file -c".  You can also feed this as standard input via
  21. # unshar, or by typing "sh <file", e.g..  If this archive is complete, you
  22. # will see the following message at the end:
  23. #        "End of archive 4 (of 6)."
  24. # Contents:  COPYING circle.c edge.c
  25. # Wrapped by federico@actisb on Wed Jan  4 13:34:48 1989
  26. PATH=/bin:/usr/bin:/usr/ucb ; export PATH
  27. if test -f 'COPYING' -a "${1}" != "-c" ; then 
  28.   echo shar: Will not clobber existing file \"'COPYING'\"
  29. else
  30. echo shar: Extracting \"'COPYING'\" \(7122 characters\)
  31. sed "s/^X//" >'COPYING' <<'END_OF_FILE'
  32. X
  33. X            yahp2ps GENERAL PUBLIC LICENSE
  34. X            (Clarified 11 Feb 1988)
  35. X
  36. X Copyright (C) 1988 Richard M. Stallman
  37. X Everyone is permitted to copy and distribute verbatim copies
  38. X of this license, but changing it is not allowed.  You can also
  39. X use this wording to make the terms for other programs. 
  40. X
  41. X  The license agreements of most software companies keep you at the
  42. Xmercy of those companies.  By contrast, my general public license is
  43. Xintended to give everyone the right to share yahp2ps.  To make sure that
  44. Xyou get the rights I want you to have, I need to make restrictions that
  45. Xforbid anyone to deny you these rights or to ask you to surrender the
  46. Xrights.  Hence this license agreement. 
  47. X
  48. X  Specifically, I want to make sure that you have the right to give away
  49. Xcopies of yahp2ps, that you receive source code or else can get it if
  50. Xyou want it, that you can change yahp2ps or use pieces of it in new free
  51. Xprograms, and that you know you can do these things. 
  52. X
  53. X  To make sure that everyone has such rights, I have to forbid you to
  54. Xdeprive anyone else of these rights.  For example, if you distribute
  55. Xcopies of yahp2ps, you must give the recipients all the rights that you
  56. Xhave.  You must make sure that they, too, receive or can get the source
  57. Xcode.  And you must tell them their rights. 
  58. X
  59. X  Also, for my own protection, I must make certain that everyone finds
  60. Xout that there is no warranty for yahp2ps.  If yahp2ps is modified by
  61. Xsomeone else and passed on, I want its recipients to know that what they
  62. Xhave is not what I distributed, so that any problems introduced by
  63. Xothers will not reflect on my reputation. 
  64. X
  65. X  Therefore I (Federico Heinz) make the following terms which say what
  66. Xyou must do to be allowed to distribute or change yahp2ps. 
  67. X
  68. X
  69. X            COPYING POLICIES
  70. X
  71. X  1.  You may copy and distribute verbatim copies of yahp2ps source code
  72. Xas you receive it, in any medium, provided that you conspicuously and
  73. Xappropriately publish on each copy a valid copyright notice "Copyright
  74. X(C) 1988 Federico Heinz." (or with whatever year is appropriate); keep
  75. Xintact the notices on all files that refer to this License Agreement and
  76. Xto the absence of any warranty; and give any other recipients of the
  77. Xyahp2ps program a copy of this License Agreement along with the program. 
  78. XYou may charge a distribution fee for the physical act of transferring a
  79. Xcopy. 
  80. X
  81. X  2.  You may modify your copy or copies of yahp2ps or any portion of
  82. Xit, and copy and distribute such modifications under the terms of
  83. XParagraph 1 above, provided that you also do the following:
  84. X
  85. X    a) cause the modified files to carry prominent notices stating
  86. X    that you changed the files and the date of any change; and
  87. X
  88. X    b) cause the whole of any work that you distribute or publish,
  89. X    that in whole or in part contains or is a derivative of yahp2ps or
  90. X    any part thereof, to be licensed at no charge to all third
  91. X    parties on terms identical to those contained in this License
  92. X    Agreement (except that you may choose to grant more extensive
  93. X    warranty protection to some or all third parties, at your option).
  94. X
  95. X    c) You may charge a distribution fee for the physical act of
  96. X    transferring a copy, and you may at your option offer warranty
  97. X    protection in exchange for a fee.
  98. X
  99. XMere aggregation of another unrelated program with this program (or its
  100. Xderivative) on a volume of a storage or distribution medium does not bring
  101. Xthe other program under the scope of these terms.
  102. X
  103. X  3.  You may copy and distribute yahp2ps (or a portion or derivative of
  104. Xit, under Paragraph 2) in object code or executable form under the terms
  105. Xof Paragraphs 1 and 2 above provided that you also do one of the
  106. Xfollowing:
  107. X
  108. X    a) accompany it with the complete corresponding machine-readable
  109. X    source code, which must be distributed under the terms of
  110. X    Paragraphs 1 and 2 above; or,
  111. X
  112. X    b) accompany it with a written offer, valid for at least three
  113. X    years, to give any third party free (except for a nominal
  114. X    shipping charge) a complete machine-readable copy of the
  115. X    corresponding source code, to be distributed under the terms of
  116. X    Paragraphs 1 and 2 above; or,
  117. X
  118. X    c) accompany it with the information you received as to where the
  119. X    corresponding source code may be obtained.  (This alternative is
  120. X    allowed only for noncommercial distribution and only if you
  121. X    received the program in object code or executable form alone.)
  122. X
  123. XFor an executable file, complete source code means all the source code for
  124. Xall modules it contains; but, as a special exception, it need not include
  125. Xsource code for modules which are standard libraries that accompany the
  126. Xoperating system on which the executable file runs.
  127. X
  128. X  4.  You may not copy, sublicense, distribute or transfer yahp2ps
  129. Xexcept as expressly provided under this License Agreement.  Any attempt
  130. Xotherwise to copy, sublicense, distribute or transfer yahp2ps is void
  131. Xand your rights to use the program under this License agreement shall be
  132. Xautomatically terminated.  However, parties who have received computer
  133. Xsoftware programs from you with this License Agreement will not have
  134. Xtheir licenses terminated so long as such parties remain in full
  135. Xcompliance. 
  136. X
  137. X  5.  If you wish to incorporate parts of yahp2ps into other free
  138. Xprograms whose distribution conditions are different, write to the
  139. XFederico Heinz, Beusselstr.  21, D-1000 Berlin 21, West Germany.  I have
  140. Xnot yet worked out a simple rule that can be stated here, but I will
  141. Xoften permit this.  I will be guided by the two goals of preserving the
  142. Xfree status of all derivatives of my free software and of promoting the
  143. Xsharing and reuse of software. 
  144. X
  145. XYour comments and suggestions about my licensing policies and my
  146. Xsoftware are welcome! Please contact the Federico Heinz, Beusselstr. 21,
  147. XD-1000 Berlin 21, West Germany, or call (+49 30) 396 77 92. 
  148. X
  149. X               NO WARRANTY
  150. X
  151. X  BECAUSE yahp2ps IS LICENSED FREE OF CHARGE, I PROVIDE ABSOLUTELY NO
  152. XWARRANTY, TO THE EXTENT PERMITTED BY APPLICABLE STATE LAW.  EXCEPT WHEN
  153. XOTHERWISE STATED IN WRITING, FREE SOFTWARE FOUNDATION, INC, RICHARD M. 
  154. XSTALLMAN AND/OR OTHER PARTIES PROVIDE yahp2ps "AS IS" WITHOUT WARRANTY
  155. XOF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO,
  156. XTHE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
  157. XPURPOSE.  THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF yahp2ps
  158. XIS WITH YOU.  SHOULD yahp2ps PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL
  159. XNECESSARY SERVICING, REPAIR OR CORRECTION. 
  160. X
  161. X IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW WILL RICHARD M. 
  162. XSTALLMAN, THE FREE SOFTWARE FOUNDATION, INC., AND/OR ANY OTHER PARTY WHO
  163. XMAY MODIFY AND REDISTRIBUTE yahp2ps AS PERMITTED ABOVE, BE LIABLE TO YOU
  164. XFOR DAMAGES, INCLUDING ANY LOST PROFITS, LOST MONIES, OR OTHER SPECIAL,
  165. XINCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY
  166. XTO USE (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING RENDERED
  167. XINACCURATE OR LOSSES SUSTAINED BY THIRD PARTIES OR A FAILURE OF THE
  168. XPROGRAM TO OPERATE WITH ANY OTHER PROGRAMS) yahp2ps, EVEN IF YOU HAVE
  169. XBEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES, OR FOR ANY CLAIM BY ANY
  170. XOTHER PARTY. 
  171. X
  172. END_OF_FILE
  173. if test 7122 -ne `wc -c <'COPYING'`; then
  174.     echo shar: \"'COPYING'\" unpacked with wrong size!
  175. fi
  176. # end of 'COPYING'
  177. fi
  178. if test -f 'circle.c' -a "${1}" != "-c" ; then 
  179.   echo shar: Will not clobber existing file \"'circle.c'\"
  180. else
  181. echo shar: Extracting \"'circle.c'\" \(9416 characters\)
  182. sed "s/^X//" >'circle.c' <<'END_OF_FILE'
  183. X/*
  184. X        HPGL to PostScript converter
  185. X   Copyright (C) 1988 (and following) Federico Heinz
  186. X
  187. Xyahp2ps is distributed in the hope that it will be useful, but WITHOUT ANY
  188. XWARRANTY.  No author or distributor accepts responsibility to anyone
  189. Xfor the consequences of using it or for whether it serves any
  190. Xparticular purpose or works at all, unless he says so in writing.
  191. XRefer to the Free Software Foundation's General Public License for full details.
  192. X
  193. XEveryone is granted permission to copy, modify and redistribute yahp2ps,
  194. Xbut only under the conditions described in the GNU General Public
  195. XLicense.  A copy of this license is supposed to have been given to you
  196. Xalong with yahp2ps so you can know your rights and responsibilities.  It
  197. Xshould be in a file named COPYING.  Among other things, the copyright
  198. Xnotice and this notice must be preserved on all copies.
  199. X
  200. XIn other words, go ahead and share yahp2ps, but don't try to stop
  201. Xanyone else from sharing it farther.  Help stamp out software hoarding!
  202. X
  203. Xyahp2ps is TOTALLY unrelated to GNU or the Free Software Foundation,
  204. Xit is only released under the same conditions.
  205. X
  206. X    For bug reports, wishes, etc. send e-mail to
  207. X
  208. X    ...!mcvax!unido!tub!actisb!federico  (from Europe)
  209. X    ...!uunet!pyramid!actisb!federico    (from anywhere else)
  210. X
  211. X    For Physical mail:
  212. X
  213. X    Federico Heinz
  214. X    Beusselstr. 21
  215. X    1000 Berlin 21
  216. X
  217. X    Tel. (+49 30) 396 77 92
  218. X
  219. X*/
  220. X/**************************************************************************
  221. X
  222. X   Arithmetical support for circle/arc stuff
  223. X
  224. X**************************************************************************/
  225. X
  226. X#include <ctype.h>
  227. X#include "defs.h"
  228. X#include "circle.h"
  229. X#include "io.h"
  230. X
  231. X
  232. X/**************************************************************************
  233. X
  234. X  Trigonometry stuff, where I can give free fly to my floating-point
  235. X  hate and my love for letting the compiler do the job.
  236. X
  237. X**************************************************************************/
  238. X
  239. X
  240. X
  241. X/* Table to convert the normalized angle returned by octantAngle to
  242. X   it's "equivalent" in the specified octant */
  243. X
  244. X
  245. Xtypedef struct
  246. X  { int     sign;
  247. X    Number  base;
  248. X    Boolean swappedFncts;
  249. X    int     cosineFactor;
  250. X    int     sineFactor;
  251. X  } Octant;
  252. X
  253. X
  254. X
  255. Xstatic Octant OctantTable[]=
  256. X  { { 1, Zero,         False,  1,  1},
  257. X    {-1, OneSquare,    True,   1,  1},
  258. X    { 1, OneSquare,    True,  -1,  1},
  259. X    {-1, TwoSquares,   False, -1,  1},
  260. X    { 1, TwoSquares,   False, -1, -1},
  261. X    {-1, ThreeSquares, True,  -1, -1},
  262. X    { 1, ThreeSquares, True,   1, -1},
  263. X    {-1, FullCircle,   False,  1, -1}
  264. X  };
  265. X
  266. X
  267. X/*
  268. X
  269. X  Map an angle to the first octant and return a pointer to the octant
  270. X  conversion structure that enables to do inter-octant mapping. The
  271. X  mapped angle is in INTEGER degrees, not Number.
  272. X
  273. X*/
  274. X
  275. Xstatic Octant *classifyAngle(angle)
  276. X
  277. XNumber *angle;
  278. X
  279. X{ Number result;
  280. X  Octant *octant;
  281. X
  282. X  *angle = *angle % FullCircle;
  283. X  if (*angle < Zero)
  284. X    *angle = FullCircle + *angle;
  285. X  octant = OctantTable + *angle / (OneSquare / 2);
  286. X  result = (*angle % OneSquare) / One;
  287. X  if (result > ((OneSquare / One) / 2))
  288. X    *angle = (OneSquare / One) - result;
  289. X  else
  290. X    *angle = result;
  291. X  return(octant);
  292. X}
  293. X
  294. X
  295. X
  296. X/*
  297. X
  298. X  Normalize the cathetes such that:
  299. X                                    they're both positive
  300. X                                    the X cathete is longer than the Y.
  301. X  Return also a pointer to the octant conversion structure that enables
  302. X  to map an angle from the 1st octant into the cathetes' octant.
  303. X
  304. X*/
  305. X
  306. Xstatic Octant *classifyCathetes(target, cathetes)
  307. X
  308. XCoordinatePair target, cathetes;
  309. X
  310. X{ Number dummy;
  311. X  int    octant;
  312. X
  313. X  if (cathetes[Y] >= Zero)
  314. X  { target[Y] = cathetes[Y];
  315. X    octant = 0;
  316. X  }
  317. X  else
  318. X  { target[Y] = -cathetes[Y];
  319. X    octant = 4;
  320. X  }
  321. X  if (cathetes[X] >= Zero)
  322. X  { target[X] = cathetes[X];
  323. X    if (octant) octant |= 3;
  324. X  }
  325. X  else
  326. X  { target[X] = -cathetes[X];
  327. X    if (!octant) octant |= 3;
  328. X  }
  329. X  if (target[X] < target[Y])
  330. X  { octant ^= 1;
  331. X    dummy = target[X];
  332. X    target[X] = target[Y];
  333. X    target[Y] = dummy;
  334. X  }
  335. X  return(OctantTable + octant);
  336. X}
  337. X
  338. X
  339. X
  340. X/*
  341. X
  342. X  These tables contain the values for the cosine, sine and tangent of
  343. X  all integer angles between 0 and 45 degrees (or at least so says my
  344. X  math library).
  345. X
  346. X*/
  347. X
  348. Xstatic Number CosineTable[] = {
  349. X  10000L,  9998L,  9993L,  9986L,  9975L,  9961L,  9945L,  9925L,
  350. X   9902L,  9876L,  9848L,  9816L,  9781L,  9743L,  9702L,  9659L,
  351. X   9612L,  9563L,  9510L,  9455L,  9396L,  9335L,  9271L,  9205L,
  352. X   9135L,  9063L,  8987L,  8910L,  8829L,  8746L,  8660L,  8571L,
  353. X   8480L,  8386L,  8290L,  8191L,  8090L,  7986L,  7880L,  7771L,
  354. X   7660L,  7547L,  7431L,  7313L,  7193L,  7071L };
  355. X
  356. Xstatic Number SineTable[] = {
  357. X      0L,   174L,   348L,   523L,   697L,   871L,  1045L,  1218L,
  358. X   1391L,  1564L,  1736L,  1908L,  2079L,  2249L,  2419L,  2588L,
  359. X   2756L,  2923L,  3090L,  3255L,  3420L,  3583L,  3746L,  3907L,
  360. X   4067L,  4226L,  4383L,  4539L,  4694L,  4848L,  4999L,  5150L,
  361. X   5299L,  5446L,  5591L,  5735L,  5877L,  6018L,  6156L,  6293L,
  362. X   6427L,  6560L,  6691L,  6819L,  6946L,  7071L };
  363. X
  364. Xstatic int TangentTable[] = {
  365. X      0,   174,   349,   524,   699,   874,  1051,  1227,
  366. X   1405,  1583,  1763,  1943,  2125,  2308,  2493,  2679,
  367. X   2867,  3057,  3249,  3443,  3639,  3838,  4040,  4244,
  368. X   4452,  4663,  4877,  5095,  5317,  5543,  5773,  6008,
  369. X   6248,  6494,  6745,  7002,  7265,  7535,  7812,  8097,
  370. X   8390,  8692,  9004,  9325,  9656, 10000 };
  371. X
  372. X
  373. X/*
  374. X
  375. X  Search the angle corresponding to a certain value in the table.
  376. X
  377. X*/
  378. X
  379. Xstatic int search(value, table)
  380. X
  381. Xint value, table[];
  382. X
  383. X{ int lo, hi, mid;
  384. X
  385. X  lo = 0; hi = 45;
  386. X  while (lo <= hi)
  387. X  { mid = (lo + hi) / 2;
  388. X    if (value < table[mid])
  389. X      hi = mid - 1;
  390. X    else if (value > table[mid])
  391. X      lo = mid + 1;
  392. X    else
  393. X      return(mid);
  394. X  }
  395. X  return((value-table[hi] < table[lo]-value) ? hi : lo);
  396. X}
  397. X
  398. X
  399. X
  400. X/*
  401. X
  402. X  Compute the only 1st-octant angle that can generate these cathetes.
  403. X
  404. X*/
  405. X
  406. Xstatic Number octantAngle(cathetes)
  407. X
  408. XCoordinatePair cathetes;
  409. X
  410. X{ int tangent;
  411. X
  412. X  tangent = (int)divNum(cathetes[Y], cathetes[X]);
  413. X  return(search(tangent, TangentTable) * One);
  414. X}
  415. X
  416. X
  417. X
  418. X/*
  419. X
  420. X  Compute the only angle that can generate these cathetes.
  421. X
  422. X*/
  423. X
  424. Xstatic Number arcTangent(cathetes)
  425. X
  426. XCoordinatePair cathetes;
  427. X
  428. X{ Octant *octant;
  429. X  CoordinatePair normalizedCathetes;
  430. X
  431. X  octant = classifyCathetes(normalizedCathetes, cathetes);
  432. X  return(octantAngle(normalizedCathetes) * octant->sign + octant->base);
  433. X}
  434. X
  435. X
  436. X
  437. X/*
  438. X
  439. X  Compute the cosine of an angle.
  440. X
  441. X*/
  442. X
  443. Xstatic Number cosine(angle)
  444. X
  445. XNumber angle;
  446. X
  447. X{ Octant *octant;
  448. X
  449. X  octant = classifyAngle(&angle);
  450. X  return((octant->swappedFncts ? SineTable[angle] : CosineTable[angle])
  451. X          * octant->cosineFactor);
  452. X}
  453. X
  454. X   
  455. X
  456. X/*
  457. X
  458. X  Compute the sine of an angle.
  459. X
  460. X*/
  461. X
  462. Xstatic Number sine(angle)
  463. X
  464. XNumber angle;
  465. X
  466. X{ Octant *octant;
  467. X
  468. X  octant = classifyAngle(&angle);
  469. X  return((octant->swappedFncts ? CosineTable[angle] : SineTable[angle])
  470. X          * octant->sineFactor);
  471. X}
  472. X
  473. X   
  474. X
  475. X/*************************************************************************
  476. X
  477. X   Coordinate computing stuff
  478. X
  479. X*************************************************************************/
  480. X
  481. X
  482. X/*
  483. X
  484. X  Set target to the coordinates of the point that is located at
  485. X  polar coordinates (radius, angle) from center.
  486. X
  487. X*/
  488. X
  489. Xvoid polarToCartesian(target, center, radius, angle)
  490. X
  491. XCoordinatePair target, center;
  492. XNumber radius, angle;
  493. X
  494. X{ target[X] = center[X] + mulNum(cosine(angle), radius);
  495. X  target[Y] = center[Y] + mulNum(sine(angle), radius);
  496. X}
  497. X
  498. X
  499. X
  500. X
  501. X/*
  502. X
  503. X   Compute radius and angle given an offset to the center.
  504. X
  505. X*/
  506. X
  507. Xvoid cartesianToPolar(radius, angle, offset)
  508. X
  509. XNumber *radius, *angle;
  510. XCoordinatePair offset;
  511. X
  512. X{ Number cosineOfAngle;
  513. X
  514. X  *angle = arcTangent(offset);
  515. X  if (cosineOfAngle = cosine(*angle))    /* Watch out for cos(a) == 0!!! */
  516. X    *radius = divNum(offset[X], cosineOfAngle);
  517. X  else
  518. X    *radius = offset[X] ? offset[X] : offset[Y];
  519. X  if (*radius < 0) *radius = -*radius;
  520. X}
  521. X
  522. X
  523. X
  524. X/*
  525. X
  526. X  Return an angle suitable for a curve operation. It must divide the
  527. X  sweep angle, and must be between the minimum and maximum values specified.
  528. X  In case the sweep angle is a prime number, then compromise must be
  529. X  done. I then take the maxValue angle and make the last step
  530. X  shorter. This is not all compatible with the HP plotters, but then
  531. X  they enter an ENDLESS LOOP when this constellation occurs (at least
  532. X  mine does)
  533. X  
  534. X*/
  535. X
  536. X
  537. XNumber correctedChordAngle(maxValue, sweepAngle, minValue)
  538. X
  539. XNumber maxValue, sweepAngle, minValue;
  540. X
  541. X{ Number i;
  542. X  
  543. X  if (maxValue < 0)     /* Ignore sign */
  544. X    maxValue = -maxValue;
  545. X  maxValue = maxValue % FullCircle;
  546. X  if (maxValue < minValue)
  547. X    return(minValue);
  548. X  if (!(maxValue && (sweepAngle % maxValue)))
  549. X    return(maxValue);    /* High-resolution arc or exact division */
  550. X  i = maxValue - One;
  551. X  while(sweepAngle % i)
  552. X  { i -= One;
  553. X    if (i < minValue) return(maxValue);
  554. X  }
  555. X  return(i);
  556. X}
  557. X
  558. X
  559. X
  560. X/*
  561. X
  562. X  Twist the start and the sweep angles so as to make sense.
  563. X
  564. X*/
  565. X
  566. Xvoid fixUpStartAndSweep(startAngle, sweepAngle)
  567. X
  568. XNumber *startAngle, *sweepAngle;
  569. X
  570. X{ *startAngle = *startAngle % FullCircle;
  571. X  if ((*sweepAngle > FullCircle) || (*sweepAngle < -FullCircle))
  572. X    *sweepAngle = FullCircle;
  573. X}
  574. X
  575. X
  576. X
  577. X/*
  578. X
  579. X  Get the optional chord angle parameter.
  580. X
  581. X*/
  582. X
  583. Xvoid getChordAngle(target, sweepAngle, minValue)
  584. X
  585. XNumber *target;
  586. XNumber sweepAngle, minValue;
  587. X
  588. X{ if (isNumeric(LookAhead))
  589. X    (void)getInteger(target);
  590. X  else
  591. X    *target = DefaultChordAngle;
  592. X  *target = correctedChordAngle(*target, sweepAngle, minValue);
  593. X}
  594. X
  595. END_OF_FILE
  596. if test 9416 -ne `wc -c <'circle.c'`; then
  597.     echo shar: \"'circle.c'\" unpacked with wrong size!
  598. fi
  599. # end of 'circle.c'
  600. fi
  601. if test -f 'edge.c' -a "${1}" != "-c" ; then 
  602.   echo shar: Will not clobber existing file \"'edge.c'\"
  603. else
  604. echo shar: Extracting \"'edge.c'\" \(7129 characters\)
  605. sed "s/^X//" >'edge.c' <<'END_OF_FILE'
  606. X/*
  607. X        HPGL to PostScript converter
  608. X   Copyright (C) 1988 (and following) Federico Heinz
  609. X
  610. Xyahp2ps is distributed in the hope that it will be useful, but WITHOUT ANY
  611. XWARRANTY.  No author or distributor accepts responsibility to anyone
  612. Xfor the consequences of using it or for whether it serves any
  613. Xparticular purpose or works at all, unless he says so in writing.
  614. XRefer to the Free Software Foundation's General Public License for full details.
  615. X
  616. XEveryone is granted permission to copy, modify and redistribute yahp2ps,
  617. Xbut only under the conditions described in the GNU General Public
  618. XLicense.  A copy of this license is supposed to have been given to you
  619. Xalong with yahp2ps so you can know your rights and responsibilities.  It
  620. Xshould be in a file named COPYING.  Among other things, the copyright
  621. Xnotice and this notice must be preserved on all copies.
  622. X
  623. XIn other words, go ahead and share yahp2ps, but don't try to stop
  624. Xanyone else from sharing it farther.  Help stamp out software hoarding!
  625. X
  626. Xyahp2ps is TOTALLY unrelated to GNU or the Free Software Foundation,
  627. Xit is only released under the same conditions.
  628. X
  629. X    For bug reports, wishes, etc. send e-mail to
  630. X
  631. X    ...!mcvax!unido!tub!actisb!federico  (from Europe)
  632. X    ...!uunet!pyramid!actisb!federico    (from anywhere else)
  633. X
  634. X    For Physical mail:
  635. X
  636. X    Federico Heinz
  637. X    Beusselstr. 21
  638. X    1000 Berlin 21
  639. X
  640. X    Tel. (+49 30) 396 77 92
  641. X
  642. X*/
  643. X/***************************************************************************
  644. X
  645. X   Edge drawing stuff.
  646. X
  647. X***************************************************************************/
  648. X
  649. X
  650. X#include <ctype.h>
  651. X#include "defs.h"
  652. X#include "dispatch.h"
  653. X#include "io.h"
  654. X#include "circle.h"
  655. X#include "penctrl.h"
  656. X
  657. X
  658. X
  659. X
  660. X/**************************************************************************
  661. X
  662. X    Rectangle functions: absolute & relative.
  663. X
  664. X**************************************************************************/
  665. X
  666. X/*
  667. X
  668. X  Draw a rectangle with one corner at current position and the opposite
  669. X  at the specified absolute CoordinatePair.
  670. X
  671. X*/
  672. X
  673. X
  674. Xstatic void doRectangle(oppositeCorner)
  675. X
  676. XCoordinatePair oppositeCorner;
  677. X
  678. X{ CoordinatePair thisCorner;
  679. X  Boolean penWasUp;
  680. X
  681. X  penWasUp = PenIsUp;
  682. X  lowerPen();
  683. X  thisCorner[X] = PenPosition[X]; thisCorner[Y] = PenPosition[Y];
  684. X  doLine(thisCorner[X], oppositeCorner[Y]);
  685. X  doLine(oppositeCorner[X], oppositeCorner[Y]);
  686. X  doLine(oppositeCorner[X], thisCorner[Y]);
  687. X  doLine(thisCorner[X], thisCorner[Y]);
  688. X  if (penWasUp) liftPen();
  689. X}
  690. X
  691. X
  692. X
  693. X
  694. X/*
  695. X
  696. X  Draw a rectangle, interprete the coordinates as absolute.
  697. X
  698. X*/
  699. X
  700. XCommandImplementation rectangleAbsolute()
  701. X
  702. X{ CoordinatePair corner;
  703. X
  704. X  if (getCoordinatePair(corner))
  705. X    doRectangle(corner);
  706. X  endCommand();
  707. X}
  708. X
  709. X
  710. X
  711. X
  712. X/*
  713. X
  714. X  Draw a rectangle, interprete the coordinates relative to PenPosition
  715. X
  716. X*/
  717. X
  718. XCommandImplementation rectangleRelative()
  719. X
  720. X{ CoordinatePair corner;
  721. X
  722. X  if (getCoordinatePair(corner))
  723. X  { corner[X] = PenPosition[X] + corner[X];
  724. X    corner[Y] = PenPosition[Y] + corner[Y];
  725. X    doRectangle(corner);
  726. X  }
  727. X  endCommand();
  728. X}
  729. X
  730. X
  731. X
  732. X
  733. X/***************************************************************************
  734. X
  735. X     Curve functions: wedge, circle and arc
  736. X
  737. X***************************************************************************/
  738. X
  739. X
  740. X
  741. X/*
  742. X
  743. X  Move the pen along an arc. The pen must already be at the start
  744. X  of the arc. The chordAngle should divide the sweepAngle and (of course)
  745. X  be != 0. If it does not divide the sweepAngle, then the last chord
  746. X  will be shorter.
  747. X
  748. X*/
  749. X
  750. Xvoid doArc(center, radius, startAngle, sweepAngle, chordAngle)
  751. X
  752. XCoordinatePair center;
  753. XNumber radius, startAngle, sweepAngle, chordAngle;
  754. X
  755. X{ Number currentAngle, endAngle;
  756. X  CoordinatePair thisPoint;
  757. X  int times;
  758. X
  759. X  times = sweepAngle / chordAngle;
  760. X  if (times < 0)
  761. X  { chordAngle = -chordAngle;
  762. X    times = -times;
  763. X  }
  764. X  currentAngle = startAngle;
  765. X  while (times--)
  766. X  { currentAngle = currentAngle + chordAngle;
  767. X    polarToCartesian(thisPoint, center, radius, currentAngle);
  768. X    doLine(thisPoint[X], thisPoint[Y]);
  769. X  }
  770. X  if (sweepAngle % chordAngle)
  771. X  { polarToCartesian(thisPoint, center, radius, startAngle + sweepAngle);
  772. X    doLine(thisPoint[X], thisPoint[Y]);
  773. X  }
  774. X}
  775. X
  776. X
  777. X
  778. X/*
  779. X
  780. X  Draw a wedge with center at PenPosition.
  781. X
  782. X*/
  783. X
  784. XCommandImplementation wedge()
  785. X
  786. X{ CoordinatePair wedgeCenter, beginOfArc;
  787. X  Number radius, startAngle, sweepAngle, chordAngle;
  788. X  Boolean penWasUp;
  789. X
  790. X  if (getNumber(&radius) &&
  791. X      getInteger(&startAngle) &&
  792. X      getInteger(&sweepAngle))
  793. X  { penWasUp = PenIsUp;
  794. X    fixUpStartAndSweep(&startAngle, &sweepAngle);
  795. X    getChordAngle(&chordAngle, sweepAngle, MinimumChordForWedge);
  796. X    if (chordAngle > MaximumChordAngle)
  797. X      warning("Chord angle out of range.");
  798. X    else
  799. X    { wedgeCenter[X] = PenPosition[X];
  800. X      wedgeCenter[Y] = PenPosition[Y];
  801. X      polarToCartesian(beginOfArc, wedgeCenter, radius, startAngle);
  802. X      lowerPen();
  803. X      doLine(beginOfArc[X],beginOfArc[Y]);
  804. X      doArc(wedgeCenter, radius, startAngle, sweepAngle, chordAngle);
  805. X      doLine(wedgeCenter[X], wedgeCenter[Y]);
  806. X    }
  807. X    if (penWasUp) liftPen();
  808. X    endCommand();
  809. X  }
  810. X}
  811. X
  812. X
  813. X
  814. XCommandImplementation circle()
  815. X
  816. X{ CoordinatePair center, beginOfArc;
  817. X  Number radius, chordAngle;
  818. X  Boolean penWasUp;
  819. X
  820. X  if (getNumber(&radius))
  821. X  { getChordAngle(&chordAngle, FullCircle, Zero);
  822. X    center[X] = PenPosition[X];
  823. X    center[Y] = PenPosition[Y];
  824. X    penWasUp = PenIsUp;
  825. X    liftPen();
  826. X    if (chordAngle)
  827. X    { polarToCartesian(beginOfArc, center, radius, Zero);
  828. X      doLine(beginOfArc[X],beginOfArc[Y]);
  829. X      lowerPen();
  830. X      doArc(center, radius, Zero, FullCircle, chordAngle);
  831. X      liftPen();
  832. X    }
  833. X    else /* smoothest circle */
  834. X    { doHRArc(center, radius, Zero, FullCircle);
  835. X      stroke();
  836. X    }
  837. X    doLine(center[X], center[Y]);
  838. X    if (!penWasUp) lowerPen();
  839. X  }
  840. X  endCommand();
  841. X}
  842. X
  843. X
  844. X
  845. X/*
  846. X
  847. X  Draw an arc using Absolute coordinates.
  848. X
  849. X*/
  850. X
  851. Xstatic void doAbsoluteArc(center, sweepAngle, chordAngle)
  852. X
  853. XCoordinatePair center;
  854. XNumber chordAngle, sweepAngle;
  855. X
  856. X{ Number radius, startAngle;
  857. X  CoordinatePair delta;
  858. X
  859. X  delta[X] = PenPosition[X] - center[X];
  860. X  delta[Y] = PenPosition[Y] - center[Y];
  861. X  cartesianToPolar(&radius, &startAngle, delta);
  862. X  fixUpStartAndSweep(&startAngle, &sweepAngle);
  863. X  if (chordAngle)
  864. X    doArc(center, radius, startAngle, sweepAngle, chordAngle);
  865. X  else /* smoothest circle */
  866. X  { if (!PenIsUp)
  867. X      doHRArc(center, radius, startAngle, sweepAngle);
  868. X    polarToCartesian(PenPosition, center, radius, startAngle + sweepAngle);
  869. X  }
  870. X}
  871. X
  872. X
  873. X
  874. X/*
  875. X
  876. X  Arc Absolute command
  877. X
  878. X*/
  879. X
  880. XCommandImplementation arcAbsolute()
  881. X
  882. X{ CoordinatePair center;
  883. X  Number sweepAngle, chordAngle;
  884. X  
  885. X  if (getCoordinatePair(center) &&
  886. X      getInteger(&sweepAngle))
  887. X  { getChordAngle(&chordAngle, sweepAngle, Zero);
  888. X    doAbsoluteArc(center, sweepAngle, chordAngle);
  889. X  }
  890. X  endCommand();
  891. X}
  892. X
  893. X
  894. X
  895. X/*
  896. X
  897. X  Arc Relative command
  898. X
  899. X*/
  900. X
  901. XCommandImplementation arcRelative()
  902. X
  903. X{ CoordinatePair center;
  904. X  Number sweepAngle, chordAngle;
  905. X  
  906. X  if (getCoordinatePair(center) &&
  907. X      getInteger(&sweepAngle))
  908. X  { getChordAngle(&chordAngle, sweepAngle, Zero);
  909. X    center[X] = PenPosition[X] + center[X];
  910. X    center[Y] = PenPosition[Y] + center[Y];
  911. X    doAbsoluteArc(center, sweepAngle, chordAngle);
  912. X  }
  913. X  endCommand();
  914. X}
  915. END_OF_FILE
  916. if test 7129 -ne `wc -c <'edge.c'`; then
  917.     echo shar: \"'edge.c'\" unpacked with wrong size!
  918. fi
  919. # end of 'edge.c'
  920. fi
  921. echo shar: End of archive 4 \(of 6\).
  922. cp /dev/null ark4isdone
  923. MISSING=""
  924. for I in 1 2 3 4 5 6 ; do
  925.     if test ! -f ark${I}isdone ; then
  926.     MISSING="${MISSING} ${I}"
  927.     fi
  928. done
  929. if test "${MISSING}" = "" ; then
  930.     echo You have unpacked all 6 archives.
  931.     rm -f ark[1-9]isdone
  932. else
  933.     echo You still need to unpack the following archives:
  934.     echo "        " ${MISSING}
  935. fi
  936. ##  End of shell archive.
  937. exit 0
  938.